package mgdb

import (
	"gitee.com/daledi/public/vmap"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

// MgoDB mongodb
type MgoDB struct {
	*mgo.Database
	Prefix string
}

//New 创建新的mgdb对象
func New(db *mgo.Database, prefix string) MgoDB {
	return MgoDB{db, prefix}
}

// Coll 获取collection对象。
func (mgodb MgoDB) Coll(table string) *mgo.Collection {
	return mgodb.C(mgodb.Prefix + table)
}

//LimitUpdate 重新封装的mongodb的Update，屏蔽了对指定status的更新
func (mgodb MgoDB) LimitUpdate(mgocoll string, skey, data vmap.V) error {
	c := mgodb.Coll(mgocoll)
	skey["status"] = vmap.V{"$nin": []int{-1000, -2000}}
	err := c.Update(skey, data)
	return err
}

//LimitQuery 查询可管理的内容。屏蔽status为-1000和-2000的内容
func (mgodb MgoDB) LimitQuery(mgocoll string, key interface{}, result interface{}, pageSize, pageNo int, selector vmap.V) (int, error) {
	var skey vmap.V
	switch key.(type) {
	case bson.ObjectId:
		skey = vmap.V{"_id": key.(bson.ObjectId)}
	case []bson.ObjectId:
		skey = vmap.V{"_id": vmap.V{"$in": key.([]bson.ObjectId)}}
	case vmap.V:
		skey = key.(vmap.V)
	case string:
		skey = vmap.V{"name": key.(string)}
	}
	skey["status"] = vmap.V{"$nin": []int{-1000, -2000}}
	rnum, err := mgodb.Query(mgocoll, skey, result, pageSize, pageNo, selector)
	return rnum, err
}

//Query 搜索mongodb
func (mgodb MgoDB) Query(mgocoll string, key interface{}, result interface{}, pageSize, pageNo int, selector vmap.V) (int, error) {
	var skey vmap.V
	switch key.(type) {
	case bson.ObjectId:
		skey = vmap.V{"_id": key.(bson.ObjectId)}
	case []bson.ObjectId:
		skey = vmap.V{"_id": vmap.V{"$in": key.([]bson.ObjectId)}}
	case vmap.V:
		skey = key.(vmap.V)
	case string:
		skey = vmap.V{"name": key.(string)}
	}
	c := mgodb.Coll(mgocoll)
	//	c := mgo.C(mdbprefix + mgocoll)
	qSeg := c.Find(skey)
	if orderby, ok := selector["orderby"]; ok {
		var sort []string
		switch orderby.(type) {
		case string:
			sort = append(sort, orderby.(string))
		case []string:
			sort = append(sort, orderby.([]string)...)
		case []interface{}:
			for _, value := range orderby.([]interface{}) {
				sort = append(sort, value.(string))
			}
		}
		//sort := orderby.([]string)
		delete(selector, "orderby")
		qSeg = qSeg.Sort(sort...).Select(selector)
	} else {
		qSeg = qSeg.Select(selector)
	}
	var rnum int
	var err error
	if pageNo > 0 && pageSize > 0 {
		skip := (pageNo - 1) * pageSize
		qSeg = qSeg.Skip(skip).Limit(pageSize)
		err = qSeg.All(result)
	} else {
		err = qSeg.One(result)
	}
	if err != nil {
		return 0, err
	}
	rnum, err = qSeg.Count()
	return rnum, err
}
